#include "dedup.h"

struct meta_lru {
    struct meta_lru *prev, *next;
    struct metadata_blk *blk;
};

#define LIST_REMOVE(p) (p)->prev->next = (p)->next; (p)->next->prev = (p)->prev;
#define LIST_INSERT(p, head) (p)->next = (head)->next; (p)->prev = head; (head)->next->prev = p; (head)->next = p;

int data_fd, meta_fd;
int datacnt = 0, metacnt = 0;
struct metadata_blk *tmp_blk, *curr_blk;
struct meta_lru meta_lru_head = {&meta_lru_head, &meta_lru_head, NULL};
int metablk_inMem = 0;

#ifndef metablk_inMem_max
#define metablk_inMem_max 1
#endif

typedef struct buffer_queue {
    struct buffer_queue *next;
    char *buf;
    int size;
    off_t offset;
} buffer_queue_t;

buffer_queue_t *buffer_queue_head = NULL, *buffer_queue_tail = NULL;

/**
 * 正常的活动需要读写元数据文件, 所以如果想要延迟元数据写
 * 就需要hook掉meta_fd, 将其放入普通的文件(非目标文件系统)进行读写
 * 在对meta_fd的正常写请求中, 就需要先对hook掉的meta_fd执行写操作, 然后再将该操作放入链表中保存
*/
#ifdef DELAY_WRITE
int meta_fd_bak;
int buffered_write_cnt;
void add_buffer_queue(char *buf, int size, off_t offset) {
    Pwrite(meta_fd, buf, size, offset); // 为了维持程序正常读写的运行
    buffer_queue_t *p = Malloc(sizeof(buffer_queue_t));
    allocate_align((void **)&p->buf, size);
    memcpy(p->buf, buf, size);
    p->size = size;
    p->offset = offset;
    p->next = NULL;
    if (buffer_queue_tail) {
        buffer_queue_tail->next = p;
        buffer_queue_tail = p;
    } else {
        buffer_queue_head = buffer_queue_tail = p;
    }
}
#define bWriteMeta(pbn, content) add_buffer_queue(content, BLKSZ, BLKSZ * pbn)
#else
#define bWriteMeta(pbn, content) Pwrite(meta_fd, content, BLKSZ, BLKSZ * pbn)
#endif

#define bWriteData(pbn, content) Pwrite(data_fd, content, BLKSZ, BLKSZ * pbn)
